﻿using Framework.Core;
using Framework.Core.Io;
using Framework.Remoting.Client;
using Framework.Remoting.Conventions;
using Framework.Tests.Wcf.Client.ServiceDefinition;
using Rhino.Mocks;
using Xunit;

namespace Framework.Tests.Wcf.Client
{
    extern alias castlecore;

    public interface IProxyContract : castlecore::Castle.DynamicProxy.IProxyTargetAccessor, IContract
    {
    }

    public class WcfExtensionTest
    {
        private static readonly castlecore::Castle.DynamicProxy.ProxyGenerator ProxyGenerator =
            new castlecore::Castle.DynamicProxy.ProxyGenerator();

        private readonly castlecore::Castle.DynamicProxy.IInterceptor interceptorMock;

        private readonly MockRepository mockRepository;

        private readonly IProxyContract proxyContractMock;

        public WcfExtensionTest()
        {
            mockRepository = new MockRepository();
            interceptorMock = mockRepository.StrictMock<castlecore::Castle.DynamicProxy.IInterceptor>();
            proxyContractMock = mockRepository.StrictMock<IProxyContract>();
        }

        [Fact]
        public void Should_throw_wcf_proxy_exception_when_instance_is_not_proxy()
        {
            Assert.Throws<WcfProxyException>(() => new object().Close());
        }

        [Fact]
        public void Should_throw_wcf_proxy_exception_when_instance_is_not_wcf_interceptor()
        {
            Assert.Throws<WcfProxyException>(() => ProxyGenerator.CreateClassProxy<object>(interceptorMock).Close());
        }

        [Fact]
        public void Should_close()
        {
            var wcfInterceptor = new WcfInterceptor<IContract>(EnvMode.Prod, new ChannelPerRequest(), 
                                                               new WcfServiceInfoFactory(new ConfigurationManagerAdapter(), new BindingFactory(), new ProtocolFactory()));
            ((castlecore::Castle.DynamicProxy.IProxyTargetAccessor) proxyContractMock).Expect(x => x.GetInterceptors()).
                Return(new castlecore::Castle.DynamicProxy.IInterceptor[] {wcfInterceptor});

            mockRepository.ReplayAll();
            proxyContractMock.Close<IContract>();
            mockRepository.VerifyAll();
        }

        [Fact]
        public void Should_do_nothing_when_instance_is_null()
        {
            WcfExtension.Close<IContract>(null);
        }
    }
}